module GYLite
{
		
	
	export class GYSeqImage extends GYImage
	{
		public static default_interval:number = 100;
		protected _seqArr:Array<any>;
		protected _seqIndex:number;
		protected _startTime:number;
		protected _intervalTime:number;
		protected _isRunning:number;
		protected _startIndex:number;
		protected _waitSource:any;
		protected _sourceWaitRate:number;
		protected _loopTimes:number;
		protected _reserveEnd:Boolean;
		private _reserving:Boolean;
		protected _loops:number;
		protected _frameNum:number;
		private _endFunc:Function;
		private _updateFunc:Function;
		private _endObject:any;
		private _updateObject:any;
		private _endIndex:number;		

		public get seqArr():Array<any>
		{
			return this._seqArr;
		}

		public get frameNum():number
		{
			return this._frameNum;
		}
		public get seqIndex():number
		{
			return this._seqIndex;
		}			
		
		public constructor()
		{
			super();
			var s = this;
			s.initComponent();
		}
		protected initComponent():void
		{
			var s = this;
			s._seqArr=null;
			s._seqIndex=0;
			s._startTime=0;			
			s._isRunning=0;
			s._startIndex=0;
			s._waitSource=null;			
			s._loopTimes=0;
			s._loops = Number.MAX_VALUE;
			s._frameNum = 0;
			s._endFunc = null;
			s._updateFunc = null;
			s._reserving = false;
			s._reserveEnd = false;
			s._updateObject= null;
			s._endObject = null;
			s._intervalTime = GYSeqImage.default_interval;
			s._sourceWaitRate = -1;
			s._endIndex = Number.MAX_VALUE;
		}
		public get source():any
		{
			var s = this;
			return egret.superGetter(GYSeqImage, s, "source");
		}
		public set source(bmp:any)
		{
			var s = this;
			s.baseSource(bmp);			
		}
		/**结束回调，
		 * val endFunc(loopTimes) 参数为已播放几次,
		 * */
		public setEndFunc(val:Function, thisObject:any):void
		{
			var s = this;
			s._endFunc = val;
			s._endObject = thisObject;
		}
		/**更新回调
		 *  val endFunc(index) 参数为当前第几帧
		 * */
		public setUpdateFunc(val:Function, thisObject:any):void
		{
			var s = this;
			s._updateFunc = val;
			s._updateObject = thisObject;
		}
		protected baseSource(bmp:any):void
		{let s = this;
			if(bmp == s._mySource.texture)
				return;
			if(s._sourceWaitRate > -1)
			{
				if(s._isRunning == 1)
				{
					s._waitSource = bmp;
					return;
				}
			}
			s.setSource(bmp);
		}
		private setSource(bmp:any):void
		{
			var s = this;
			if(bmp instanceof Array)
			{
				if(s.$width == s.$width)
					s.scaleX=s.$width/bmp[0].width;
				if(s.$height == s.$height)
					s.scaleY=s.$height/bmp[0].height;
				if(s._isRunning == 0)
					s.start(bmp,s._seqIndex);
				else
					s.reset(bmp,s._seqIndex);
				return;
			}
			if(s._isRunning == 1)
			{
				s._isRunning = 2;
				CommonUtil.delStageLoop(s.loop,s);
			}
			if(bmp)
			{
				if(s.$width == s.$width)
					s.scaleX=s.$width/bmp.width;
				if(s.$height == s.$height)
					s.scaleY=s.$height/bmp.height;
			}
			s._mySource.texture=bmp;		
			s._mySource.smoothing = s._smoothing;
			s.invalidDisplay();
		}
		/**序列帧播放
		 * @ind 起始索引
		 * */
		public start(seq:Array<any>, seqInd:number=0):void
		{
			var s = this;
			if(seq == null && s._seqArr == null)return;
			s.reset(seq,seqInd);
			if(s._isRunning == 1)return;
			s._isRunning = 1;
			CommonUtil.addStageLoop(s.loop,s);
		}
		private reset(seq:Array<any>, seqInd:number=0):void
		{let s = this;
			if(seq)s._seqArr = seq;
			s._frameNum = s._seqArr.length;
			s._startTime = CommonUtil.loopTime;
			s._seqIndex = s._startIndex = seqInd<s._frameNum?seqInd:s._frameNum-1;
			s._loopTimes = 0;
			s.sourceWaitRate = s._sourceWaitRate;			
			egret.superSetter(GYSeqImage, s, "source", s._seqArr[s._seqIndex]);
		}
		/**停止序列帧
		 * @ind 如果-1，这清理序列帧 如果是大于-1，则停止在ind索引的图片显示
		 * */
		public stop(ind:number=-1):void
		{
			var s = this;
			if(s._isRunning == 1)
			{				
				CommonUtil.delStageLoop(s.loop,s);
			}
			if(ind == -1)
			{
				s._isRunning = 0;
				s._seqArr = null;
				s.baseSource(null);				
				return;
			}
			s._isRunning = 2;
			if(s._seqArr)
			{
				s._seqIndex = ind < s._frameNum?ind:s._frameNum - 1;
				s.baseSource(s._seqArr[s._seqIndex]);
			}			
		}
		private loop(t:number):void
		{
			var s = this;
			t = t - s._startTime;
			var i:number,ls:number;
			i = (s._startIndex + t / s._intervalTime >> 0);
			ls = i / s._frameNum >> 0;
			if(ls != s._loopTimes)
			{
				s._reserving = !s._reserving;
				s._loopTimes= ls;
				if(ls >= s._loops)
				{
					s.stop(s._endIndex);
					if(s._endFunc!=null)s._endFunc(s._endObject, s._loopTimes);				
					return;
				}
				if(s._endFunc!=null)s._endFunc(s._endObject, s._loopTimes);				
			}
			i %=s._frameNum;
			if(s._reserving && s._reserveEnd)
			{
				i = s._frameNum -  i - 1;
			}
			if(i == s._seqIndex)return;
			if(s._updateFunc!=null)s._updateFunc.call(s._updateObject,i);
			s._seqIndex = i;
			if(s._waitSource && s._seqIndex == s._sourceWaitRate)
			{
				s.setSource(s._waitSource);
				s._waitSource = null;
				return;
			}			
			s._mySource.texture = s._seqArr[s._seqIndex];
			s._mySource.smoothing = s._smoothing;
		}
		/**序列帧间隔(毫秒)* */
		public get intervalTime():number
		{
			var s = this;
			return s._intervalTime;
		}

		public set intervalTime(value:number)
		{
			var s = this;
			s._intervalTime = value;
		}

		public get isRunning():number
		{
			var s = this;
			return s._isRunning;
		}
		/**切换图片时需要达到的帧数（当是序列帧动画） */
		public get sourceWaitRate():number
		{
			var s = this;
			return s._sourceWaitRate;
		}

		public set sourceWaitRate(value:number)
		{
			var s = this;
			if(s._sourceWaitRate == value)return;
			s._sourceWaitRate = value;
			if(s._seqArr && s._sourceWaitRate >= s._frameNum)
				s._sourceWaitRate  = s._frameNum - 1;
		}

		public get reserveEnd():Boolean
		{
			var s = this;
			return s._reserveEnd;
		}

		public set reserveEnd(value:Boolean)
		{
			var s = this;
			s._reserveEnd = value;
		}
		/**循环多少次停止*/
		public get loops():number
		{
			var s = this;
			return s._loops;
		}

		public set loops(value:number)
		{
			var s = this;
			s._loops = value;
		}

		public dispose(disposeChild:boolean=true, removeChild:boolean = true, forceDispose:boolean=false):void
		{
			let s =this;
			s.stop();
			s.setUpdateFunc(null,null);
			s.setEndFunc(null,null);
			super.dispose(disposeChild, removeChild, forceDispose);
		}
	}
}